home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS14.ADF / Progs / CSquared / CSquared.c < prev    next >
C/C++ Source or Header  |  1989-01-28  |  44KB  |  1,416 lines

  1. /*
  2.  
  3.  CircleSquared from Sept. '86 Scientific American "Computer Recreations"
  4.  column produces wildly colorful but mathematically precise patterns on
  5.  your Amiga display.  There is also a treatment of this topic in the
  6.  Oct. '86 issue of Computer Language in their "Theory & Practice" column.
  7.  It doesn't take nearly as long as the generation of a Mandelbrot either.
  8.  
  9.  The program is controlled thru standard intuition menus, gadgets,
  10.  and requesters.  Most of the important operating parameters, i.e. corna,
  11.  cornb, side, and modval, are modifiable thru these gadgets, requesters,
  12.  menues and such.
  13.  
  14.    corna  - the X coordinate of the upper left hand corner of the window
  15.    cornb  - the Y coordinate of the upper left hand corner of the window
  16.    side   - the length of the side of the square
  17.    modval - the modulus value that determines the color of the pixel at
  18.             the point(i, j)
  19.  
  20.  The following calculations are made for each point plotted on the display.
  21.  Note that this routine, PlotPoints(), was written using the Motorola
  22.  Fast Floating Point library.
  23.  
  24.    x = corna + side * i/linesize
  25.    y = cornb + side * j/linesize
  26.    z = x * x + y * y
  27.    c = z MOD modval
  28.  
  29.  The point at coordinates (i,j) is colored with color "c".  Note that
  30.  the palette of colors is also modifiable thru another requester
  31.  containing sixteen color selection gadgets.  Three proportional
  32.  gadgets allow the modification the Red, Green, and Blue components
  33.  of the selected color.
  34.  
  35.  The CLOSEWINDOW gadget causes the program to exit.
  36.  
  37.  Also note that there is a Hi-Res mode of operation.  Instead of invoking
  38.  the program (from the CLI) as "CSquared" include a runtime parameter of
  39.  "-h" such that the new invocation becomes "CSquared -h".  Lo-Res is the
  40.  default mode of operation.
  41.  
  42.  I freely admit that this program is a hack and was strictly done for
  43.  my own personal entertainment.  I am new to C so if you see any wretched
  44.  code perhaps you will be understanding.  (I'm also new to the Amiga.)
  45.  I am placing this program into the public domain although if you make use
  46.  of major portions of the code please give credit where credit is due.
  47.  (I'd like to see my name up in lights, too.)  Have fun!
  48.  
  49.  This program compiles cleanly under Lattice C version 3.03.  No other
  50.  external routines are required except for some of those found in Lattice's
  51.  LC.LIB and, of course, AMIGA.LIB.  The standard c.o startup code is also
  52.  used as well.
  53.  
  54.  Author:      Bill DuPree (with many thanks to Rob Peck)  
  55.  Date:        09/23/86
  56.  
  57.  Address BIX mail to bdupree.
  58.  Address written correspondence to:
  59.  
  60.       Bill DuPree
  61.       434 W. Wellington #505
  62.       Chicago, IL. 60657
  63. */
  64.  
  65. /* DEFINES ********************************************************** */
  66.  
  67. /* Gadget ID's - Note ID's 1 - 16 are used by color gadgets in palette */
  68.  
  69. #define RCONTROL 17
  70. #define GCONTROL 18
  71. #define BCONTROL 19
  72. #define NEWMOD   20
  73. #define NEWSIDE  21
  74. #define NEWCORNA 22
  75. #define NEWCORNB 23
  76. #define RESUME   24
  77.  
  78. /* Screen and Window parameters */
  79.  
  80. #define XMIN 2
  81. #define YMIN 10
  82. #define DEPTH  4
  83.  
  84. #define INTUITION_MESSAGE (1<<intuitionMsgBit)
  85.  
  86. #define CloseConsole(x) CloseDevice(x)
  87.  
  88. /* INCLUDES ********************************************************** */
  89.  
  90. #include "lattice/math.h"
  91. #include "exec/types.h"
  92. #include "exec/io.h"
  93. #include "exec/memory.h"
  94.  
  95. #include "graphics/gfx.h"
  96. #include "hardware/dmabits.h"
  97. #include "hardware/custom.h"
  98. #include "hardware/blit.h"
  99. #include "graphics/gfxmacros.h"
  100. #include "graphics/copper.h"
  101. #include "graphics/view.h"
  102. #include "graphics/gels.h"
  103. #include "graphics/regions.h"
  104. #include "graphics/clip.h"
  105. #include "exec/exec.h"
  106. #include "graphics/text.h"
  107. #include "graphics/gfxbase.h"
  108.  
  109. #include "devices/console.h"
  110. #include "devices/keymap.h"
  111.  
  112. #include "libraries/dos.h"
  113. #include "graphics/text.h"
  114. #include "libraries/diskfont.h"
  115. #include "intuition/intuition.h"
  116.  
  117. /* EXTERNALS ***************************************************** */
  118.  
  119. extern struct Window *OpenWindow();
  120. extern struct Screen *OpenScreen();
  121. extern struct MsgPort *CreatePort();
  122. extern struct IOStdReq *CreateStdIO();
  123. extern int SPFlt(), SPFieee(), SPAdd(), SPMul(), SPDiv(), SPFix();
  124.  
  125. /* GLOBALS ****************************************************** */
  126.  
  127. union kludge {    /* can't use float directly for FFP because C */
  128.    float num;     /* convert float to double in expressions and */
  129.    int   i;       /* when passing parameters.                   */
  130. } side, corna, cornb;
  131.  
  132. USHORT class;       /* values obtained from IntuiMessages */
  133. USHORT code;
  134. USHORT qualifier;
  135. USHORT mode;
  136. APTR address;       /* address of the gadget which we hit */
  137.  
  138. char Title[32];
  139. USHORT CurrentColor; /* currently selected color gadget */
  140. int modval;          /* modulus value used to determine number of colors */
  141. int sideval;         /* length of side */
  142.  
  143. int NotDone, TimeToStop, wakeupmask, intuitionMsgBit, MaxHeight, MaxWidth;
  144.  
  145. long IntuitionBase=0;
  146. long GfxBase=0;
  147. long MathBase=0;
  148. long MathTransBase=0;
  149.  
  150. struct Gadget ColorGadg[16];              /* the color selection gadgets */
  151. struct Image  ColorImage[16], AltImage[16];   /* and their images */
  152.  
  153. struct IBitPlane {
  154.    USHORT IData[8];     /* Image data structures */
  155. };
  156.  
  157. struct IBitPlane NullOne = {
  158.    { 0 }
  159. };
  160.  
  161. struct IBitPlane SelectedOne = {
  162.    0x0000,
  163.    0x7f80,
  164.    0x7f80,
  165.    0x7f80,
  166.    0x7f80,
  167.    0x7f80,
  168.    0x7f80,
  169.    0x0000
  170. };
  171.  
  172. struct MyImageData {
  173.    struct IBitPlane Plane[4];      /* Image data for a color gadget */
  174. } *PlanePtr;
  175.  
  176. /* Gadgets, Menuitems, Requesters, etc. */
  177.  
  178. struct IntuiText ResumeMsg = {
  179.    2,1,                 /* FrontPen, BackPen */
  180.    JAM2,                /* DrawMode */
  181.    8,                   /* LeftEdge */
  182.    4,                   /* TopEdge */
  183.    NULL,                /* ITextFont */
  184.    "Resume",            /* IText */
  185.    NULL                 /* NextText */
  186. };
  187.  
  188. SHORT BGCoord[10] = { 0,0, 62,0, 62,14, 0,14, 0,0 };
  189.  
  190. struct Border BGBdr = {
  191.    1,1,                 /* LeftEdge, TopEdge */
  192.    3,2,JAM1,            /* FrontPen, BackPen, DrawMode */
  193.    5,                   /* Count */
  194.    &BGCoord[0],         /* XY */
  195.    NULL                 /* Next Border */
  196. };
  197.  
  198. struct Gadget Resume = {
  199.    NULL,                /*  NextGadget */
  200.    -74,-20,64,16,       /* LeftEdge, TopEdge, Width, Height */
  201.    GADGHCOMP |
  202.    GRELBOTTOM |
  203.    GRELRIGHT,           /* Flags */
  204.    ENDGADGET |
  205.    RELVERIFY,           /* Activation */
  206.    BOOLGADGET |
  207.    REQGADGET,           /* GadgetType */
  208.    (APTR) &BGBdr,       /* GadgetRender */
  209.    NULL,                /* SelectRender */
  210.    &ResumeMsg,          /* GadgetText */
  211.    0,                   /* MutualExclude */
  212.    NULL,                /* SpecialInfo */
  213.    RESUME,              /* GadgetID */
  214.    NULL                 /* UserData */
  215. };
  216.  
  217. struct PropInfo BPropInfo = {
  218.    AUTOKNOB | FREEHORIZ,  /* Flags */
  219.    0, 0,            /* Pots:  Horiz, Vert: both start at 0 */
  220.    0x0fff, 0x0fff,  /* Bodies: Horiz is 1/16, Vert is 1/16 */
  221.    0, 0, 0, 0, 0, 0 /* System usage stuff */
  222. };
  223.  
  224. struct Image Dmy1, Dmy2, Dmy3;
  225.  
  226. struct Gadget BGadget = {
  227.    &ColorGadg[0],             /* pointer to NextGadget */
  228.    20, 40, 192, 10,           /* Select Box L T W H */
  229.    GADGHCOMP | GADGIMAGE,     /* Flags */
  230.    RELVERIFY,                 /* Activation flags */
  231.    PROPGADGET | REQGADGET,    /* Type */
  232.    (APTR) &Dmy3, /* GadgetRender */
  233.    NULL,       /* no pointer to SelectRender */
  234.    NULL,       /* no pointer to GadgetText */
  235.    0,          /* no MutualExclude */
  236.    (APTR) &BPropInfo, /* SpecialInfo */
  237.    BCONTROL,          /* no ID */
  238.    NULL        /* no pointer to special data */
  239. };
  240.  
  241. struct PropInfo GPropInfo = {
  242.    AUTOKNOB | FREEHORIZ,  /* Flags */
  243.    0, 0,            /* Pots:  Horiz, Vert: both start at 0 */
  244.    0x0fff, 0x0fff,  /* Bodies: Horiz is 1/16, Vert is 1/16 */
  245.    0, 0, 0, 0, 0, 0 /* System usage stuff */
  246. };
  247.  
  248. struct Gadget GGadget = {
  249.    &BGadget,                  /* pointer to NextGadget */
  250.    20, 22, 192, 10,           /* Select Box L T W H */
  251.    GADGHCOMP | GADGIMAGE,     /* Flags */
  252.    RELVERIFY,                 /* Activation flags */
  253.    PROPGADGET | REQGADGET,    /* Type */
  254.    (APTR) &Dmy2, /* GadgetRender */
  255.    NULL,       /* no pointer to SelectRender */
  256.    NULL,       /* no pointer to GadgetText */
  257.    0,          /* no MutualExclude */
  258.    (APTR) &GPropInfo, /* SpecialInfo */
  259.    GCONTROL,          /* no ID */
  260.    NULL        /* no pointer to special data */
  261. };
  262.  
  263. struct PropInfo RPropInfo = {
  264.    AUTOKNOB | FREEHORIZ,  /* Flags */
  265.    0, 0,            /* Pots:  Horiz, Vert: both start at 0 */
  266.    0x0fff, 0x0fff,  /* Bodies: Horiz is 1/16, Vert is 1/16 */
  267.    0, 0, 0, 0, 0, 0 /* System usage stuff */
  268. };
  269.  
  270. struct Gadget RGadget = {
  271.    &GGadget,                  /* pointer to NextGadget */
  272.    20, 04, 192, 10,           /* Select Box L T W H */
  273.    GADGHCOMP | GADGIMAGE,     /* Flags */
  274.    RELVERIFY,                 /* Activation flags */
  275.    PROPGADGET | REQGADGET,    /* Type */
  276.    (APTR) &Dmy1, /* GadgetRender */
  277.    NULL,       /* no pointer to SelectRender */
  278.    NULL,       /* no pointer to GadgetText */
  279.    0,          /* no MutualExclude */
  280.    (APTR) &RPropInfo, /* SpecialInfo */
  281.    RCONTROL,          /* no ID */
  282.    NULL        /* no pointer to special data */
  283. };
  284.  
  285. struct IntuiText Prompt7 = {
  286.    0, 1,             /* FrontPen, BackPen */
  287.    JAM2,             /* DrawMode */
  288.    28, 82,           /* LeftEdge, TopEdge */
  289.    NULL,             /* ITextFont */
  290.    "to modify.",     /* IText */
  291.    NULL              /* NextText */
  292. };
  293.  
  294. struct IntuiText Prompt6 = {
  295.    0, 1,             /* FrontPen, BackPen */
  296.    JAM2,             /* DrawMode */
  297.    4, 72,            /* LeftEdge, TopEdge */
  298.    NULL,             /* ITextFont */
  299.    "Select the color", /* IText */
  300.    &Prompt7          /* NextText */
  301. };
  302.  
  303. struct IntuiText Prompt5 = {
  304.    0, 1,             /* FrontPen, BackPen */
  305.    JAM2,             /* DrawMode */
  306.    4, 40,            /* LeftEdge, TopEdge */
  307.    NULL,             /* ITextFont */
  308.    "B",              /* IText */
  309.    &Prompt6          /* NextText */
  310. };
  311.  
  312. struct IntuiText Prompt4 = {
  313.    0, 1,             /* FrontPen, BackPen */
  314.    JAM2,             /* DrawMode */
  315.    4, 22,            /* LeftEdge, TopEdge */
  316.    NULL,             /* ITextFont */
  317.    "G",              /* IText */
  318.    &Prompt5          /* NextText */
  319. };
  320.  
  321. struct IntuiText Prompt3 = {
  322.    0, 1,             /* FrontPen, BackPen */
  323.    JAM2,             /* DrawMode */
  324.    4, 4,             /* LeftEdge, TopEdge */
  325.    NULL,             /* ITextFont */
  326.    "R",              /* IText */
  327.    &Prompt4          /* NextText */
  328. };
  329.  
  330. SHORT RCoords2[10] = { 0,0,  194,0,  194,12,  0,12,  0,0 };
  331.  
  332. struct Border ColorsBord = {
  333.    12, 54,        /* LeftEdge, TopEdge */
  334.    0, 1, JAM1,    /* FrontPen, BackPen, DrawMode */
  335.    5,             /* Count */
  336.    &RCoords2[0],  /* XY */
  337.    NULL           /* NextBorder */
  338. };
  339.  
  340. SHORT RCoords1[10] = { 0,0,  217,0,  217,99,  0,99,  0,0 };
  341.  
  342. struct Border ReqBord1 = {
  343.    1, 1,          /* LeftEdge, TopEdge */
  344.    0, 1, JAM1,    /* FrontPen, BackPen, DrawMode */
  345.    5,             /* Count */
  346.    &RCoords1[0],  /* XY */
  347.    &ColorsBord    /* NextBorder */
  348. };
  349.  
  350. struct Requester ColorParms = {
  351.    NULL,          /* OlderRequest */
  352.    2, 12,         /* LeftEdge, TopEdge */
  353.    220, 102,      /* Width, Height */
  354.    0, 0,          /* RelLeft, RelTop */
  355.    &RGadget,      /* ReqGadget */
  356.    &ReqBord1,     /* ReqBorder */
  357.    &Prompt3,      /* ReqText */
  358.    0,             /* Flags */
  359.    1,             /* BackFill */
  360.    NULL,          /* ReqLayer */
  361.    {NULL},        /* Pad */
  362.    NULL,          /* ImageBmap */
  363.    NULL,          /* RWindow (system) */
  364.    {NULL}         /* Pad */
  365. };
  366.  
  367. UBYTE NCBString[6], NCBUndo[6];
  368.  
  369. struct StringInfo NCBStr = {
  370.    &NCBString[0],        /* Buffer */
  371.    &NCBUndo[0],          /* UndoBuffer */
  372.    0,                   /* BufferPos */
  373.    6,                   /* MaxChars */
  374.    0, 0, 0, 0,          /* DispPos, UndoPos, NumChars, DispCount */
  375.    0, 0,                /* CLeft, CTop */
  376.    NULL,                /* LayerPtr */
  377.    0,                   /* LongInt */
  378.    NULL                 /* AltKeyMap */
  379. };
  380.  
  381. struct Gadget NewCornb = {
  382.    &Resume,             /* NextGadget */
  383.    15,76,40,8,          /* LeftEdge, TopEdge, Width, Height */
  384.    GADGHCOMP,           /* Flags */
  385.    LONGINT,             /* Activation */
  386.    STRGADGET |
  387.    REQGADGET,           /* GadgetType */
  388.    NULL,                /* GadgetRender */
  389.    NULL,                /* SelectRender */
  390.    NULL,                /* GadgetText */
  391.    0,                   /* MutualExclude */
  392.    (APTR) &NCBStr,      /* SpecialInfo */
  393.    NEWCORNB,            /* GadgetID */
  394.    NULL                 /* UserData */
  395. };
  396.  
  397. UBYTE NCAString[6], NCAUndo[6];
  398.  
  399. struct StringInfo NCAStr = {
  400.    &NCAString[0],        /* Buffer */
  401.    &NCAUndo[0],          /* UndoBuffer */
  402.    0,                   /* BufferPos */
  403.    6,                   /* MaxChars */
  404.    0, 0, 0, 0,          /* DispPos, UndoPos, NumChars, DispCount */
  405.    0, 0,                /* CLeft, CTop */
  406.    NULL,                /* LayerPtr */
  407.    0,                   /* LongInt */
  408.    NULL                 /* AltKeyMap */
  409. };
  410.  
  411. struct Gadget NewCorna = {
  412.    &NewCornb,            /* NextGadget */
  413.    15,56,40,8,          /* LeftEdge, TopEdge, Width, Height */
  414.    GADGHCOMP,           /* Flags */
  415.    LONGINT,             /* Activation */
  416.    STRGADGET |
  417.    REQGADGET,           /* GadgetType */
  418.    NULL,                /* GadgetRender */
  419.    NULL,                /* SelectRender */
  420.    NULL,                /* GadgetText */
  421.    0,                   /* MutualExclude */
  422.    (APTR) &NCAStr,      /* SpecialInfo */
  423.    NEWCORNA,            /* GadgetID */
  424.    NULL                 /* UserData */
  425. };
  426.  
  427. UBYTE NSString[6], NSUndo[6];
  428.  
  429. struct StringInfo NSStr = {
  430.    &NSString[0],        /* Buffer */
  431.    &NSUndo[0],          /* UndoBuffer */
  432.    0,                   /* BufferPos */
  433.    6,                   /* MaxChars */
  434.    0, 0, 0, 0,          /* DispPos, UndoPos, NumChars, DispCount */
  435.    0, 0,                /* CLeft, CTop */
  436.    NULL,                /* LayerPtr */
  437.    0,                   /* LongInt */
  438.    NULL                 /* AltKeyMap */
  439. };
  440.  
  441. struct Gadget NewSide = {
  442.    &NewCorna,           /* NextGadget */
  443.    15,36,40,8,          /* LeftEdge, TopEdge, Width, Height */
  444.    GADGHCOMP,           /* Flags */
  445.    LONGINT,             /* Activation */
  446.    STRGADGET |
  447.    REQGADGET,           /* GadgetType */
  448.    NULL,                /* GadgetRender */
  449.    NULL,                /* SelectRender */
  450.    NULL,                /* GadgetText */
  451.    0,                   /* MutualExclude */
  452.    (APTR) &NSStr,       /* SpecialInfo */
  453.    NEWSIDE,             /* GadgetID */
  454.    NULL                 /* UserData */
  455. };
  456.  
  457. UBYTE NMString[4], NMUndo[4];
  458.  
  459. struct StringInfo NMStr = {
  460.    &NMString[0],        /* Buffer */
  461.    &NMUndo[0],          /* UndoBuffer */
  462.    0,                   /* BufferPos */
  463.    4,                   /* MaxChars */
  464.    0, 0, 0, 0,          /* DispPos, UndoPos, NumChars, DispCount */
  465.    0, 0,                /* CLeft, CTop */
  466.    NULL,                /* LayerPtr */
  467.    0,                   /* LongInt */
  468.    NULL                 /* AltKeyMap */
  469. };
  470.  
  471. struct Gadget NewModulus = {
  472.    &NewSide,            /* NextGadget */
  473.    15,16,24,8,          /* LeftEdge, TopEdge, Width, Height */
  474.    GADGHCOMP,           /* Flags */
  475.    LONGINT,             /* Activation */
  476.    STRGADGET |
  477.    REQGADGET,           /* GadgetType */
  478.    NULL,                /* GadgetRender */
  479.    NULL,                /* SelectRender */
  480.    NULL,                /* GadgetText */
  481.    0,                   /* MutualExclude */
  482.    (APTR) &NMStr,       /* SpecialInfo */
  483.    NEWMOD,              /* GadgetID */
  484.    NULL                 /* UserData */
  485. };
  486.  
  487. struct IntuiText NCBTxt = {
  488.    0, 1,             /* FrontPen, BackPen */
  489.    JAM2,             /* DrawMode */
  490.    8, 66,            /* LeftEdge, TopEdge */
  491.    NULL,             /* ITextFont */
  492.    "Initial Y coordinate", /* IText */
  493.    NULL              /* NextText */
  494. };
  495.  
  496. struct IntuiText NCATxt = {
  497.    0, 1,             /* FrontPen, BackPen */
  498.    JAM2,             /* DrawMode */
  499.    8, 46,            /* LeftEdge, TopEdge */
  500.    NULL,             /* ITextFont */
  501.    "Initial X coordinate", /* IText */
  502.    &NCBTxt           /* NextText */
  503. };
  504.  
  505. struct IntuiText NSRange = {
  506.    2, 1,             /* FrontPen, BackPen */
  507.    JAM2,             /* DrawMode */
  508.    56, 36,           /* LeftEdge, TopEdge */
  509.    NULL,             /* ITextFont */
  510.    "side > 0", /* IText */
  511.    &NCATxt           /* NextText */
  512. };
  513.  
  514. struct IntuiText NSTxt = {
  515.    0, 1,             /* FrontPen, BackPen */
  516.    JAM2,             /* DrawMode */
  517.    8, 26,            /* LeftEdge, TopEdge */
  518.    NULL,             /* ITextFont */
  519.    "Enter a new side value", /* IText */
  520.    &NSRange          /* NextText */
  521. };
  522.  
  523. struct IntuiText ModRange = {
  524.    2, 1,             /* FrontPen, BackPen */
  525.    JAM2,             /* DrawMode */
  526.    56, 16,           /* LeftEdge, TopEdge */
  527.    NULL,             /* ITextFont */
  528.    "(2 <= modulus <= 16)", /* IText */
  529.    &NSTxt            /* NextText */
  530. };
  531.  
  532. struct IntuiText ModPrompt = {
  533.    0, 1,             /* FrontPen, BackPen */
  534.    JAM2,             /* DrawMode */
  535.    8, 6,             /* LeftEdge, TopEdge */
  536.    NULL,             /* ITextFont */
  537.    "Enter a new modulus value", /* IText */
  538.    &ModRange         /* NextText */
  539. };
  540.  
  541. SHORT NumCoords[10] = { 0,0,  217,0,  217,97,  0,97,  0,0 };
  542.  
  543. struct Border NumReqBord = {
  544.    1, 1,          /* LeftEdge, TopEdge */
  545.    0, 1, JAM1,    /* FrontPen, BackPen, DrawMode */
  546.    5,             /* Count */
  547.    &NumCoords[0], /* XY */
  548.    NULL           /* NextBorder */
  549. };
  550.  
  551. struct Requester NumericParms = {
  552.    NULL,          /* OlderRequest */
  553.    2, 12,         /* LeftEdge, TopEdge */
  554.    220, 100,      /* Width, Height */
  555.    0, 0,          /* RelLeft, RelTop */
  556.    &NewModulus,   /* ReqGadget */
  557.    &NumReqBord,   /* ReqBorder */
  558.    &ModPrompt,    /* ReqText */
  559.    0,             /* Flags */
  560.    1,             /* BackFill */
  561.    NULL,          /* ReqLayer */
  562.    {NULL},        /* Pad */
  563.    NULL,          /* ImageBmap */
  564.    NULL,          /* RWindow (system) */
  565.    {NULL}         /* Pad */
  566. };
  567.  
  568. SHORT RCoord2[10] = { 0,0,  247,0,  247,47,  0,47,  0,0 };
  569.  
  570. struct Border ReqBord2 = {
  571.    1, 1,          /* LeftEdge, TopEdge */
  572.    0, 1, JAM1,    /* FrontPen, BackPen, DrawMode */
  573.    5,             /* Count */
  574.    &RCoord2[0],   /* XY */
  575.    NULL           /* NextBorder */
  576. };
  577.  
  578. struct IntuiText BadValMsg2 = {
  579.    0, 1,             /* FrontPen, BackPen */
  580.    JAM2,             /* DrawMode */
  581.    6, 14,            /* LeftEdge, TopEdge */
  582.    NULL,             /* ITextFont */
  583.    "Value was not changed", /* IText */
  584.    NULL              /* NextText */
  585. };
  586.  
  587. UBYTE ValMsg[32];
  588.  
  589. struct IntuiText BadValMsg = {
  590.    0, 1,             /* FrontPen, BackPen */
  591.    JAM2,             /* DrawMode */
  592.    6, 4,             /* LeftEdge, TopEdge */
  593.    NULL,             /* ITextFont */
  594.    &ValMsg[0],       /* IText */
  595.    &BadValMsg2       /* NextText */
  596. };
  597.  
  598. struct Requester BadNum = {
  599.    NULL,          /* OlderRequest */
  600.    35, 20,        /* LeftEdge, TopEdge */
  601.    250, 50,       /* Width, Height */
  602.    0, 0,          /* RelLeft, RelTop */
  603.    &Resume,       /* ReqGadget */
  604.    &ReqBord2,     /* ReqBorder */
  605.    &BadValMsg,    /* ReqText */
  606.    0,             /* Flags */
  607.    1,             /* BackFill */
  608.    NULL,          /* ReqLayer */
  609.    {NULL},        /* Pad */
  610.    NULL,          /* ImageBmap */
  611.    NULL,          /* RWindow (system) */
  612.    {NULL}         /* Pad */
  613. };
  614.  
  615. struct IntuiText PaletteText = {
  616.    0, 1,             /* FrontPen, BackPen */
  617.    JAM2,             /* DrawMode */
  618.    0, 0,             /* LeftEdge, TopEdge */
  619.    NULL,             /* ITextFont */
  620.    "Palette   ",     /* IText */
  621.    NULL              /* NextText */
  622. };
  623.  
  624. struct IntuiText NumericText = {
  625.    0, 1,             /* FrontPen, BackPen */
  626.    JAM2,             /* DrawMode */
  627.    0, 0,             /* LeftEdge, TopEdge */
  628.    NULL,             /* ITextFont */
  629.    "Numeric   ",     /* IText */
  630.    NULL              /* NextText */
  631. };
  632.  
  633. struct IntuiText ParmText = {
  634.    0, 1,             /* FrontPen, BackPen */
  635.    JAM2,             /* DrawMode */
  636.    0, 0,             /* LeftEdge, TopEdge */
  637.    NULL,             /* ITextFont */
  638.    "Parameters",     /* IText */
  639.    NULL              /* NextText */
  640. };
  641.  
  642. struct IntuiText NewText = {
  643.    0, 1,             /* FrontPen, BackPen */
  644.    JAM2,             /* DrawMode */
  645.    0, 0,             /* LeftEdge, TopEdge */
  646.    NULL,             /* ITextFont */
  647.    "New       ",     /* IText */
  648.    NULL              /* NextText */
  649. };
  650.  
  651. struct IntuiText StopText = {
  652.    0, 1,             /* FrontPen, BackPen */
  653.    JAM2,             /* DrawMode */
  654.    0, 0,             /* LeftEdge, TopEdge */
  655.    NULL,             /* ITextFont */
  656.    "Stop      ",     /* IText */
  657.    NULL              /* NextText */
  658. };
  659.  
  660. struct IntuiText StartText = {
  661.    0, 1,             /* FrontPen, BackPen */
  662.    JAM2,             /* DrawMode */
  663.    0, 0,             /* LeftEdge, TopEdge */
  664.    NULL,             /* ITextFont */
  665.    "Start     ",     /* IText */
  666.    NULL              /* NextText */
  667. };
  668.  
  669. struct MenuItem PaletteItem = {
  670.    NULL,              /* NextItem */
  671.    79, 12, 80, 8,     /* LeftEdge, TopEdge, Width, Height */
  672.    ITEMTEXT |
  673.    ITEMENABLED |
  674.    HIGHCOMP,         /* Flags */
  675.    0,                /* MutualExclude */
  676.    (APTR) &PaletteText, /* ItemFill */
  677.    NULL,             /* SelectFill */
  678.    0,                /* Command */
  679.    NULL,             /* SubItem */
  680.    0                 /* NextSelect */
  681. };
  682.  
  683. struct MenuItem NumItem = {
  684.    &PaletteItem,     /* NextItem */
  685.    79, 2, 80, 8,     /* LeftEdge, TopEdge, Width, Height */
  686.    ITEMTEXT |
  687.    ITEMENABLED |
  688.    HIGHCOMP,         /* Flags */
  689.    0,                /* MutualExclude */
  690.    (APTR) &NumericText, /* ItemFill */
  691.    NULL,             /* SelectFill */
  692.    0,                /* Command */
  693.    NULL,             /* SubItem */
  694.    0                 /* NextSelect */
  695. };
  696.  
  697. struct MenuItem ParmItem = {
  698.    NULL,             /* NextItem */
  699.    0, 30, 80, 8,     /* LeftEdge, TopEdge, Width, Height */
  700.    ITEMTEXT |
  701.    ITEMENABLED |
  702.    HIGHCOMP,         /* Flags */
  703.    0,                /* MutualExclude */
  704.    (APTR) &ParmText, /* ItemFill */
  705.    NULL,             /* SelectFill */
  706.    0,                /* Command */
  707.    &NumItem,             /* SubItem */
  708.    0                 /* NextSelect */
  709. };
  710.  
  711. struct MenuItem NewItem = {
  712.    &ParmItem,        /* NextItem */
  713.    0, 20, 80, 8,     /* LeftEdge, TopEdge, Width, Height */
  714.    ITEMTEXT |
  715.    ITEMENABLED |
  716.    HIGHCOMP,         /* Flags */
  717.    0,                /* MutualExclude */
  718.    (APTR) &NewText,  /* ItemFill */
  719.    NULL,             /* SelectFill */
  720.    0,                /* Command */
  721.    NULL,             /* SubItem */
  722.    0                 /* NextSelect */
  723. };
  724.  
  725. struct MenuItem StopItem = {
  726.    &NewItem,         /* NextItem */
  727.    0, 10, 80, 8,     /* LeftEdge, TopEdge, Width, Height */
  728.    ITEMTEXT |
  729.    ITEMENABLED |
  730.    HIGHCOMP,         /* Flags */
  731.    0,                /* MutualExclude */
  732.    (APTR) &StopText, /* ItemFill */
  733.    NULL,             /* SelectFill */
  734.    0,                /* Command */
  735.    NULL,             /* SubItem */
  736.    0                 /* NextSelect */
  737. };
  738.  
  739. struct MenuItem StartItem = {
  740.    &StopItem,        /* NextItem */
  741.    0, 0, 80, 8,      /* LeftEdge, TopEdge, Width, Height */
  742.    ITEMTEXT |
  743.    HIGHCOMP,         /* Flags */
  744.    0,                /* MutualExclude */
  745.    (APTR) &StartText, /* ItemFill */
  746.    NULL,             /* SelectFill */
  747.    0,                /* Command */
  748.    NULL,             /* SubItem */
  749.    0                 /* NextSelect */
  750. };
  751.  
  752. struct Menu CCMenu = {
  753.    NULL,             /* NextMenu */
  754.    16, 0, 56, 0,     /* LeftEdge, TopEdge, Width, Height */
  755.    MENUENABLED,      /* Flags */
  756.    "Options",        /* MenuName */
  757.    &StartItem        /* FirstItem */
  758. };
  759.  
  760. struct NewWindow nwGraphics = {
  761.       0, 0,             /* start position */
  762.       0, 0,             /* width, height are filled in later */
  763.       0, 1,             /* detail pen, block pen */
  764.       MENUPICK | GADGETUP |
  765.       CLOSEWINDOW,      /* IDCMP flags */
  766.       WINDOWCLOSE | SMART_REFRESH | NOCAREREFRESH |
  767.       ACTIVATE,         /* window flags */
  768.       NULL,             /* pointer to first user gadget */
  769.       NULL,             /* pointer to user checkmark  */ 
  770.       "",               /* window title */
  771.       NULL,             /* pointer to screen    (later) */
  772.       NULL,             /* pointer to superbitmap */
  773.       50,40,0,0,        /* sizing limits min and max */
  774.       CUSTOMSCREEN      /* type of screen in which to open */
  775.       };
  776.  
  777. struct NewScreen Any_Res_Screen = {
  778.    0, 0,                      /* LeftEdge, TopEdge */
  779.    0, 0,                      /* Width, Height are filled in later */
  780.    DEPTH,                     /* Depth */
  781.    0, 1,                      /* DetailPen, BlockPen */
  782.    0,                         /* ViewModes */
  783.    CUSTOMSCREEN,              /* Type */
  784.    NULL,                      /* Font */
  785.    "",                        /* DefaultTitle */
  786.    NULL,                      /* Gadgets */
  787.    NULL                       /* CustomBitMap */
  788. };
  789.  
  790. struct RastPort *rpG;               /* rastport at which to render */
  791. struct IntuiMessage *message;       /* the message the IDCMP sends us */
  792. struct Screen *sG;
  793. struct Window *wG;
  794.  
  795. UWORD colortable[] = { 0x000, 0xfff,        /* black, white */
  796.                        0xf00, 0xf70,        /* ruby, orange */
  797.                        0xff0, 0x7f0,        /* yellow, lime */
  798.                        0x0f0, 0x0f7,        /* green, aqua */
  799.                        0x0ff, 0x07f,        /* turquoise, blue-green */
  800.                        0x00f, 0x70f,        /* blue, maroon */
  801.                        0xf0f, 0x707,        /* purple, deep purple */
  802.                        0xa84, 0x888 };      /* brown, gray */
  803.  
  804. main(argc, argv)
  805. int argc;
  806. char *argv[];
  807. {
  808.       int problem;
  809.       struct ColorMap *oldcmap;
  810.  
  811.       /* Let's initialize some stuff first */
  812.  
  813.       PlanePtr =   /* get some chip RAM for gadget image data */
  814.          (struct MyImageData *) AllocMem(16 * sizeof(struct MyImageData),
  815.          MEMF_CHIP | MEMF_CLEAR);
  816.  
  817.       if (PlanePtr == 0) {
  818.          printf("Memory allocation error\n");
  819.          exit(20);
  820.       }
  821.  
  822.       strcpy(NSString,"160");  /* set initial side value */
  823.       strcpy(NCAString,"-15"); /* set initial corner values */
  824.       strcpy(NCBString,"-20");
  825.       strcpy(NMString,"2");    /* set initial modulus value */
  826.  
  827.       InitGadgetList();        /* Put together palette gadgets */
  828.  
  829.       if ((argc == 2) &&
  830.          ((strcmp(argv[1],"-h") == 0) || (strcmp(argv[1],"-H") == 0))) {
  831.          MaxHeight = 400;
  832.          MaxWidth  = 640;
  833.          Any_Res_Screen.ViewModes = LACE | HIRES;
  834.       }
  835.       else {
  836.          MaxHeight = 200;
  837.          MaxWidth = 320;
  838.       }
  839.  
  840.       /* Initialize any dynamic screen and window parameters */
  841.  
  842.       Any_Res_Screen.Width = MaxWidth;
  843.       Any_Res_Screen.Height = MaxHeight;
  844.       nwGraphics.Width = MaxWidth;
  845.       nwGraphics.Height = MaxHeight;
  846.       nwGraphics.MaxWidth = MaxWidth;
  847.       nwGraphics.MaxHeight = MaxHeight;
  848.  
  849.    /* Open all necessary libraries */
  850.  
  851.       if ((MathBase = OpenLibrary("mathffp.library",0)) < 1) {
  852.          printf("mathffp library open failed\n");
  853.          problem = 100;
  854.          goto cleanup0;
  855.       }
  856.  
  857.       if ((MathTransBase = OpenLibrary("mathtrans.library",0)) < 1) {
  858.          printf("mathtrans library open failed\n");
  859.          problem = 200;
  860.          goto cleanup0;
  861.       }
  862.  
  863.       GfxBase = OpenLibrary("graphics.library", 0);
  864.       if (GfxBase == NULL)
  865.       {
  866.             printf("graphics library open failed\n");
  867.             problem = 1;
  868.             goto cleanup1;
  869.       }
  870.       IntuitionBase = OpenLibrary("intuition.library", 0);
  871.       if (IntuitionBase == NULL)
  872.       {
  873.             printf("intuition library open failed\n");
  874.             problem = 2;
  875.             goto cleanup1;
  876.       }
  877.  
  878.    /* We need a custom screen for this stuff */
  879.  
  880.       sG = OpenScreen(&Any_Res_Screen);
  881.       if ( sG == NULL) {
  882.             printf("open screen failed\n");
  883.             problem = 3;
  884.             goto cleanup1a;
  885.       }
  886.  
  887.    /* Let's substitute our own color map */
  888.  
  889.       oldcmap = sG->ViewPort.ColorMap;
  890.       sG->ViewPort.ColorMap = (struct ColorMap *) GetColorMap(16);
  891.       LoadRGB4(&(sG->ViewPort), colortable, 16);
  892.       nwGraphics.Screen = sG;
  893.  
  894.       wG = OpenWindow(&nwGraphics); /* open a window for graphics*/
  895.       if ( wG == NULL ) {
  896.             printf ("open window failed\n");
  897.             problem = 4;
  898.             goto cleanup2;
  899.       }
  900.  
  901.       rpG = wG->RPort;            /* set a rastport pointer */
  902.       SetNumericValues();         /* Set window title, initialize values */
  903.       SetMenuStrip(wG, &CCMenu);  /* Attach a menu to the window */
  904.  
  905. /* find out which signals to wait for.... Intuition allocates a signal bit
  906.  for an IDCMP */
  907.  
  908.       intuitionMsgBit = wG->UserPort->mp_SigBit;
  909.  
  910. /* This code assumes that the only events we expect to wake up for are
  911.    messages from intuition arriving at the IDCMP */
  912.  
  913.       TimeToStop = FALSE;
  914.       NotDone = TRUE;
  915.       do {
  916.  
  917.             message = NULL;   /* no messages yet */
  918.  
  919.             if ((TimeToStop) ||
  920.                (NotDone = PlotPoints())) { /* display graphics rendition */
  921.  
  922.                ClearMenuStrip(wG);         /* Enable start MenuItem */
  923.                StartItem.Flags |= ITEMENABLED;
  924.                StopItem.Flags &= ~ITEMENABLED;
  925.                SetMenuStrip(wG, &CCMenu);
  926.  
  927.                wakeupmask = Wait(INTUITION_MESSAGE); /* Clear signal */
  928.      
  929.                if (message == NULL)
  930.                   message = (struct IntuiMessage *) GetMsg(wG->UserPort);
  931.  
  932.                do {
  933.                    /* empty the port then try to handle the event */
  934.                    class = message->Class;
  935.                    code =      message->Code;
  936.                    qualifier = message->Qualifier;
  937.                    address = message->IAddress;
  938.                    ReplyMsg(message);
  939.                    if ((NotDone = HandleEvent()) == FALSE) break;
  940.                }
  941.                while( (message = (struct IntuiMessage *)
  942.                       GetMsg(wG->UserPort) ) != NULL);
  943.             }
  944.  
  945.       } while (NotDone);      /* keep going until done */
  946.  
  947.    problem = 0;
  948.  
  949.    cleanup3:
  950.       ClearMenuStrip(wG);
  951.       CloseWindow(wG);
  952.    cleanup2:
  953.       FreeColorMap(sG->ViewPort.ColorMap);
  954.       sG->ViewPort.ColorMap = oldcmap;
  955.       CloseScreen(sG);
  956.    cleanup1a:
  957.       if (GfxBase != NULL) CloseLibrary(GfxBase);
  958.    cleanup1:
  959.       if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  960.    cleanup0:
  961.       if (MathTransBase != NULL) {
  962.          RemLibrary(MathTransBase);    /* allow library to be expunged */
  963.          CloseLibrary(MathTransBase);
  964.       }
  965.       if (MathBase != NULL) {
  966.          CloseLibrary(MathBase);
  967.       }
  968.  
  969.       FreeMem(PlanePtr, 16 * sizeof(struct MyImageData));
  970.  
  971.       if(problem > 0) 
  972.             exit(problem+1000);
  973.       else
  974.             return(0);
  975. }
  976.  
  977. /* This routine does the actual plotting of the points */
  978.  
  979. int PlotPoints()
  980. {
  981.    int c, ExitFlag;
  982.    register int i, j;
  983.    union kludge x, y, z, point5, linesize;
  984.  
  985.    /* Initialize some parameters. */
  986.  
  987.    point5.num = 0.5;
  988.    point5.i = SPFieee(point5.i);  /* used for rounding */
  989.  
  990.    linesize.i = MaxHeight - 3 - YMIN;
  991.    linesize.i = SPFlt(linesize.i);
  992.  
  993.    for (i = XMIN; i <= MaxWidth-3; i++) { /* one iteration per vert. line */
  994.  
  995.       for (j = YMIN; j <= MaxHeight-3; j++) {  /* one iteration per pixel */
  996.  
  997.         /* Compute: x = corna + side * i/linesize
  998.                     y = cornb + side * j/linesize
  999.                     z = x * x + y * y
  1000.                     c = z MOD modval               */
  1001.  
  1002.          x.i = SPAdd(corna.i, SPMul(side.i, SPDiv(linesize.i, SPFlt(i))));
  1003.          y.i = SPAdd(cornb.i, SPMul(side.i, SPDiv(linesize.i, SPFlt(j))));
  1004.          z.i = SPAdd(SPMul(x.i, x.i), SPMul(y.i, y.i));
  1005.          c = SPFix(SPAdd(z.i, point5.i));
  1006.          c %= modval;
  1007.  
  1008.          SetAPen(rpG, c);           /* Set new color for rendering pixel */
  1009.          WritePixel(rpG, i, j);
  1010.       }
  1011.  
  1012.       /* we poll?!!! for a message at the end of each vertical line   */
  1013.       /* It is okay to poll in this case since we have plenty of work */
  1014.       /* to do if no message is available                             */
  1015.  
  1016.       if ((message = (struct IntuiMessage *) GetMsg(wG->UserPort)) != NULL)
  1017.          if (!(ExitFlag = CheckEvent()))
  1018.             return(ExitFlag);
  1019.          else if (TimeToStop)
  1020.             break;
  1021.    }
  1022.    TimeToStop = TRUE;
  1023.    return(TRUE);
  1024. }
  1025.  
  1026. /* This routine returns FALSE to PlotPoints() is a CLOSEWINDOW event */
  1027. /* is detected.  Other events are handled thru an event handler.     */
  1028.  
  1029. int CheckEvent()
  1030. {
  1031.    int bugout;
  1032.  
  1033.    /* Note that the following call to Wait() will not put us to sleep
  1034.       because there is already a message in the port awaiting Reply().
  1035.       The only reason that we call Wait() is to clear the signal. */
  1036.  
  1037.    wakeupmask = Wait(INTUITION_MESSAGE);        /* Clear signal */
  1038.      
  1039.    do {
  1040.       /* empty the port then try to handle the event */
  1041.       class = message->Class;
  1042.       code =      message->Code;
  1043.       qualifier = message->Qualifier;
  1044.       address = message->IAddress;
  1045.       ReplyMsg(message);
  1046.       if ((bugout = HandleEvent()) == FALSE) break;
  1047.       }
  1048.    while((message = (struct IntuiMessage *) GetMsg(wG->UserPort)) != NULL);
  1049.    return(bugout);
  1050. }
  1051.  
  1052. int HandleEvent()    /* Process events */
  1053. {
  1054.    switch(class)
  1055.    {
  1056.       case CLOSEWINDOW:
  1057.             return(FALSE);
  1058.             break;
  1059.       case MENUPICK:
  1060.             MenuEvent();      /* process menu events */
  1061.             break;
  1062.    }
  1063.    class = 0;
  1064.    code = 0;
  1065.    qualifier = 0;
  1066.    address = 0;
  1067.    return(TRUE);
  1068. }
  1069.  
  1070. #define OPTIONS  0
  1071. #define START      0
  1072. #define STOP       1
  1073. #define NEW        2
  1074. #define PARAMETERS 3
  1075. #define NUMERIC      0
  1076. #define PALETTE      1
  1077.  
  1078. /* All menu events are funneled into this routine and processed here */
  1079.  
  1080. MenuEvent()
  1081. {
  1082.    USHORT MenuNumber, fnMenu, fnItem, fnSubItem;
  1083.    struct MenuItem *ItemAddress(), *Item;
  1084.  
  1085.    MenuNumber = code;
  1086.    while (MenuNumber != MENUNULL) {
  1087.       Item = ItemAddress(&CCMenu, MenuNumber);
  1088.       fnMenu = MENUNUM(MenuNumber);
  1089.       fnItem = ITEMNUM(MenuNumber);
  1090.       fnSubItem = SUBNUM(MenuNumber);
  1091.       switch(fnMenu)
  1092.       {
  1093.          case OPTIONS:
  1094.             switch(fnItem)
  1095.             {
  1096.                case START:             /* Start PlotPoints() plotting */
  1097.                   ClearMenuStrip(wG);
  1098.                   StartItem.Flags &= ~ITEMENABLED;
  1099.                   StopItem.Flags |= ITEMENABLED;
  1100.                   SetMenuStrip(wG, &CCMenu);
  1101.                   TimeToStop = FALSE;
  1102.                   break;
  1103.                case STOP:              /* stop plotting */
  1104.                   TimeToStop = TRUE;
  1105.                   break;
  1106.                case NEW:               /* Clear screen and stop plotting */
  1107.                   TimeToStop = TRUE;
  1108.                   SetAPen(rpG, 0);
  1109.                   SetOPen(rpG, 0);
  1110.                   RectFill(rpG, XMIN, YMIN, MaxWidth-2, MaxHeight-2);
  1111.                   break;
  1112.                case PARAMETERS:        /* process parameter subitems */
  1113.                   switch(fnSubItem)
  1114.                   {
  1115.                      case NUMERIC:     /* modify numeric parms */
  1116.                         ParmReq(&NumericParms);
  1117.                         SetNumericValues();
  1118.                         break;
  1119.                      case PALETTE:     /* modify palette */
  1120.                         ParmReq(&ColorParms);
  1121.                         break;
  1122.                   }
  1123.                   break;
  1124.             }
  1125.             break;
  1126.       }
  1127.       MenuNumber = Item->NextSelect;
  1128.    }
  1129. }
  1130.  
  1131. /* This routine clones the 16 color gadgets for the palette requester */
  1132.  
  1133. InitGadgetList()
  1134. {
  1135.    SHORT i, j, k;
  1136.    struct Gadget *CGadg;
  1137.    struct Image  *CImage, *AImage;
  1138.    struct MyImageData *PPtr;
  1139.  
  1140.    CGadg = ColorGadg;
  1141.    CImage = ColorImage;
  1142.    AImage = AltImage;
  1143.    PPtr = PlanePtr;
  1144.  
  1145.    for(i = 0; i <= 15; i++) {
  1146.  
  1147.       /* Initialize each color selection gadget */
  1148.  
  1149.       CGadg->NextGadget = CGadg + 1;   /* chain them together */
  1150.       CGadg->LeftEdge = i * 12 + 14;
  1151.       CGadg->TopEdge  = 56;
  1152.       CGadg->Width    = 10;
  1153.       CGadg->Height   = 8;
  1154.       CGadg->Flags    = GADGIMAGE | GADGHIMAGE;
  1155.       CGadg->Activation = RELVERIFY | TOGGLESELECT;
  1156.       CGadg->GadgetType = BOOLGADGET | REQGADGET;
  1157.       CGadg->GadgetRender = (APTR) &ColorImage[i];
  1158.       CGadg->SelectRender = (APTR) &AltImage[i];
  1159.       CGadg->GadgetText   = NULL;
  1160.       CGadg->MutualExclude = 0;
  1161.       CGadg->SpecialInfo   = NULL;
  1162.       CGadg->GadgetID      = (USHORT) i + 1;
  1163.       CGadg->UserData      = NULL;
  1164.  
  1165.    /* Images for unselected gadgets are colored rectangles */
  1166.  
  1167.       CImage->LeftEdge     = 0;
  1168.       CImage->TopEdge      = 0;
  1169.       CImage->Width        = 10;
  1170.       CImage->Height       = 8;
  1171.       CImage->Depth        = 0;
  1172.       CImage->ImageData    = NULL;
  1173.       CImage->PlanePick    = 0;
  1174.       CImage->PlaneOnOff   = (UBYTE) i;
  1175.       CImage->NextImage    = NULL;
  1176.  
  1177.    /* Alternate (selected) images are bordered colored rectangles */
  1178.  
  1179.       AImage->LeftEdge     = 0;
  1180.       AImage->TopEdge      = 0;
  1181.       AImage->Width        = 10;
  1182.       AImage->Height       = 8;
  1183.       AImage->Depth        = 4;
  1184.       AImage->ImageData    = (SHORT *) PPtr;
  1185.       AImage->PlanePick    = 0xf;
  1186.       AImage->PlaneOnOff   = 0;
  1187.       AImage->NextImage    = NULL;
  1188.  
  1189.       /* Construct image data area in CHIP RAM for each gadget */
  1190.  
  1191.       for (k = 1, j = 0; j <= 3; j++) {
  1192.          if ((k & i) != 0)
  1193.             PPtr->Plane[j] = SelectedOne;
  1194.          else
  1195.             PPtr->Plane[j] = NullOne;
  1196.          k <<= 1;
  1197.       }
  1198.  
  1199.       CGadg++;       /* bump pointers */
  1200.       CImage++;
  1201.       AImage++;
  1202.       PPtr++;
  1203.    }
  1204.    CGadg--;              /* tidy up first and last gadgets in the chain */
  1205.    CGadg->NextGadget = &Resume;
  1206.    ColorGadg[0].Flags |= SELECTED;
  1207.    CurrentColor = 0;
  1208.    SetRGBGadgets(CurrentColor);
  1209. }
  1210.  
  1211. /* This routine handles the requester processing.  Note that the */
  1212. /* requester is passed as a parameter.                           */
  1213.  
  1214. ParmReq(ReqPtr)
  1215. struct Requester *ReqPtr;
  1216. {
  1217.    Request(ReqPtr, wG);
  1218.  
  1219.    do {
  1220.       wakeupmask = Wait(INTUITION_MESSAGE);
  1221.      
  1222.       while((message = (struct IntuiMessage *)
  1223.             GetMsg(wG->UserPort)) != NULL) {
  1224.  
  1225.          /* empty the port then try to handle the event */
  1226.  
  1227.          class = message->Class;
  1228.          code =      message->Code;
  1229.          qualifier = message->Qualifier;
  1230.          address = message->IAddress;
  1231.          ReplyMsg(message);
  1232.  
  1233.       /* we do not need to go to the standard event handler since */
  1234.       /* while the requester is up all we will receive are gadget */
  1235.       /* events from the IDCMP.  Therefore we go to a special     */
  1236.       /* gadget event handler.                                    */
  1237.  
  1238.          if (GadgetEvent() == TRUE) return(0);
  1239.       }
  1240.    } while (1);
  1241. }
  1242.  
  1243. /* This routine handles the requester gadgets and their events */
  1244.  
  1245. GadgetEvent()
  1246. {
  1247.    USHORT GadgID;
  1248.  
  1249.    GadgID = ((struct Gadget *) address)->GadgetID;
  1250.    switch(class)
  1251.    {
  1252.       case GADGETUP:
  1253.             switch(GadgID)
  1254.             {
  1255.                case RESUME:
  1256.                   return(TRUE);
  1257.                   break;
  1258.                case NEWMOD:
  1259.                   break;
  1260.                case RCONTROL:
  1261.                case GCONTROL:
  1262.                case BCONTROL:
  1263.                   SetColorRegs(CurrentColor);
  1264.                   break;
  1265.                case 1:
  1266.                case 2:
  1267.                case 3:
  1268.                case 4:
  1269.                case 5:
  1270.                case 6:
  1271.                case 7:
  1272.                case 8:  /* (I'm sure there are better ways of doing this) */
  1273.                case 9:
  1274.                case 10:
  1275.                case 11:
  1276.                case 12:
  1277.                case 13:
  1278.                case 14:
  1279.                case 15:
  1280.                case 16:
  1281.                   CurrentColor = GadgID - 1;
  1282.                   SetRGBGadgets(CurrentColor);
  1283.                   ClearColorSel();
  1284.                   ColorGadg[CurrentColor].Flags |= SELECTED;
  1285.                   RefreshGadgets(&RGadget, wG, &ColorParms);
  1286.                   break;
  1287.             }
  1288.             break;
  1289.    }
  1290.    class = 0;
  1291.    code = 0;
  1292.    qualifier = 0;
  1293.    address = 0;
  1294.    return(FALSE);
  1295. }
  1296.  
  1297. /* This routine manages all three proportional gadgets and sets them */
  1298. /* up to reflect the currently selected color.                       */
  1299.  
  1300. SetRGBGadgets(Color)
  1301. USHORT Color;
  1302. {
  1303.    int rval, gval, bval;
  1304.    struct PropInfo *PIPtr;
  1305.  
  1306.    /* Isolate component values of selected color */
  1307.  
  1308.    rval = (colortable[Color] >> 8) & 0x000f;
  1309.    gval = (colortable[Color] >> 4) & 0x000f;
  1310.    bval = colortable[Color] & 0x000f;
  1311.  
  1312.    /* Initialize proportional gadgets to reflect the color values */
  1313.  
  1314.    PIPtr = (struct PropInfo *) RGadget.SpecialInfo;
  1315.    PIPtr->HorizPot = PIPtr->VertPot = (USHORT) rval * 0x0fff;
  1316.  
  1317.    PIPtr = (struct PropInfo *) GGadget.SpecialInfo;
  1318.    PIPtr->HorizPot = PIPtr->VertPot = (USHORT) gval * 0x0fff;
  1319.  
  1320.    PIPtr = (struct PropInfo *) BGadget.SpecialInfo;
  1321.    PIPtr->HorizPot = PIPtr->VertPot = (USHORT) bval * 0x0fff;
  1322. }
  1323.  
  1324. /* Routine clears selection flag from all color gadgets. */
  1325. /* This is used before re-rendering gadgets.             */
  1326.  
  1327. ClearColorSel()
  1328. {
  1329.    int i;
  1330.    struct Gadget *CGadg;
  1331.  
  1332.    CGadg = ColorGadg;
  1333.    for (i = 0; i <= 15; i++) {
  1334.       CGadg->Flags &= ~SELECTED;
  1335.       CGadg++;
  1336.    }
  1337. }
  1338.  
  1339. /* This routine reads the values off of the proportional gadgets and */
  1340. /* sets that value into the selected color register.  The modified   */
  1341. /* color table is then loaded.                                       */
  1342.  
  1343. SetColorRegs(Color)
  1344. USHORT Color;
  1345. {
  1346.    LONG rval, gval, bval;
  1347.    struct PropInfo *PIPtr;
  1348.    
  1349.    PIPtr = (struct PropInfo *) RGadget.SpecialInfo;
  1350.    rval = (((PIPtr->HorizPot + 1) * 15) + 0x8000) >> 16;
  1351.  
  1352.    PIPtr = (struct PropInfo *) GGadget.SpecialInfo;
  1353.    gval = (((PIPtr->HorizPot + 1) * 15) + 0x8000) >> 16;
  1354.  
  1355.    PIPtr = (struct PropInfo *) BGadget.SpecialInfo;
  1356.    bval = (((PIPtr->HorizPot + 1) * 15) + 0x8000) >> 16;
  1357.  
  1358.    colortable[Color] = (UWORD) ((rval << 8) | (gval << 4) | bval);
  1359.    LoadRGB4(&(sG->ViewPort), colortable, 16);
  1360. }
  1361.  
  1362. /* Routine provides initialization and edit checking for the numeric */
  1363. /* parameters.  It also constructs the and sets the window title.    */
  1364.  
  1365. SetNumericValues()
  1366. {
  1367.    int newmod, newside, SPFlt();
  1368.    char cvt[10];
  1369.  
  1370.    stcd_i(NSString, &newside);      /* convert parameters to integers */
  1371.    stcd_i(NCAString, &corna.i);     /* or perhaps FFP FLOATs          */
  1372.    strcpy(NCAUndo, NCAString);
  1373.    corna.i = SPFlt(corna.i);
  1374.    stcd_i(NCBString, &cornb.i);
  1375.    strcpy(NCBUndo, NCBString);
  1376.    cornb.i = SPFlt(cornb.i);
  1377.    stcd_i(NMString, &newmod);
  1378.  
  1379.    /* now let's do a little judicious editting */
  1380.  
  1381.    if ((newmod >= 2) && (newmod <= 16)) {
  1382.       strcpy(NMUndo, NMString);
  1383.       modval = newmod;
  1384.       strcpy(Title, "CircleSquared - Modulus: ");
  1385.       strcat(Title, NMString);
  1386.       SetWindowTitles(wG, Title, -1);
  1387.    }
  1388.    else {                     /* whoops! - modulus value is out of range */
  1389.       stci_d(cvt, modval, 10);
  1390.       strcpy(NMString, cvt);
  1391.       strcpy(NMUndo, NMString);
  1392.       strcpy(ValMsg, "Modulus value was out of range");
  1393.       Request(&BadNum, wG);
  1394.       wakeupmask = Wait(INTUITION_MESSAGE);
  1395.       while((message = (struct IntuiMessage *) GetMsg(wG->UserPort)) != NULL)
  1396.          ReplyMsg(message);
  1397.    }
  1398.  
  1399.   if (newside <= 0) {          /* make sure that side value is positive */
  1400.       stci_d(cvt, sideval, 10);
  1401.       strcpy(NSString, cvt);
  1402.       strcpy(NSUndo, NMString);
  1403.       strcpy(ValMsg, "Side value was out of range");
  1404.       Request(&BadNum, wG);
  1405.       wakeupmask = Wait(INTUITION_MESSAGE);
  1406.       while((message = (struct IntuiMessage *) GetMsg(wG->UserPort)) != NULL)
  1407.          ReplyMsg(message);
  1408.    }
  1409.    else {
  1410.       strcpy(NSUndo, NSString);
  1411.       sideval = newside;
  1412.       side.i = SPFlt(sideval);
  1413.    }
  1414. }
  1415.  
  1416.